#include "app_pool.h"
#include <mqueue.h>
#include <pthread.h>
#include "log/log.h"
#include <stdlib.h>

static char *mq_name = "/mq_pool"; // 消息队列路径  以/dev/mqueue为根目录
static mqd_t mq_fd; // 消息队列描述符
static pthread_t *thread_pool; // 线程池
static int thread_num; // 线程池大小

// 线程函数
void *thread_fun(void *arg) {
    Task task;
    // 不断的从消息队列中获取任务并执行
    while (1) {
        ssize_t len = mq_receive(mq_fd, (char *)&task, sizeof(Task), NULL);
        if (len == sizeof(Task)) {
            task.task_fun(task.arg);
        }
    }
}

int app_pool_init(int size)
{

    // 1. 创建消息队列
    struct mq_attr attr;
    attr.mq_maxmsg = 10; // 队列中最大消息数
    attr.mq_msgsize = sizeof(Task); // 每条消息的最大字节数
    mq_fd = mq_open(mq_name, O_CREAT|O_RDWR, 0644, &attr);
    if (mq_fd == -1)
    {
        log_error("创建任务队列失败");
        return -1;
    }

    // 2. 创建多个分线程
    thread_num = size;
    thread_pool = malloc(sizeof(pthread_t) * size);
    for (int i = 0; i < size; i++) {
        pthread_create(&thread_pool[i], NULL, thread_fun, NULL);
    }

    log_debug("线程池初始化成功");
    
    return 0;
}

void app_pool_destroy()
{
    // 1. 关闭并删除消息队列
    mq_close(mq_fd);
    mq_unlink(mq_name);
    // 2. 取消停止所有线程
    for (int i = 0; i < thread_num; i++) {
        pthread_cancel(thread_pool[i]);
        pthread_join(thread_pool[i], NULL);
    }
    // 3. 释放线程池
    free(thread_pool);
}

void app_pool_addTask(int (*task_fun)(void *arg), void *arg)
{
    // 1. 创建任务
    Task task = {
        .task_fun = task_fun,
        .arg = arg
    };
    // 2. 将任务添加到消息队列中
    mq_send(mq_fd, (char *)&task, sizeof(Task), 0);
}
